package com.kexio.file.entity;

import java.time.LocalDateTime;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.kexio.common.entity.BaseEntity;

/**
 * 文件信息实体类
 * 
 * 对应数据库表 sys_file_info
 * 存储文件的基本信息、元数据和业务关联信息
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@TableName("sys_file_info")
public class FileInfo extends BaseEntity {
    
    /**
     * 文件ID（主键）- UUID字符串
     */
    @TableId(value = "id", type = IdType.ASSIGN_UUID)
    private String id;
    
    /**
     * 存储对象ID
     * 关联 sys_storage_object 表，多个文件可能共享同一个存储对象（去重）
     */
    @TableField("storage_object_id")
    private String storageObjectId;
    
    /**
     * 文件原始名称
     */
    @TableField("original_name")
    private String originalName;
    
    /**
     * 文件显示名称（可修改）
     */
    @TableField("display_name")
    private String displayName;
    
    /**
     * 文件扩展名
     */
    @TableField("file_extension")
    private String fileExtension;
    
    /**
     * MIME类型
     */
    @TableField("mime_type")
    private String mimeType;
    
    /**
     * 文件大小（字节）
     */
    @TableField("file_size")
    private Long fileSize;
    
    /**
     * 文件内容MD5哈希值
     */
    @TableField("content_md5")
    private String contentMd5;
    
    /**
     * 文件内容SHA256哈希值
     */
    @TableField("content_sha256")
    private String contentSha256;
    
    /**
     * 业务键（业务系统自定义标识）
     */
    @TableField("business_key")
    private String businessKey;
    
    /**
     * 业务类型/模块（如：user-avatar, product-image等）
     */
    @TableField("business_type")
    private String businessType;
    
    /**
     * 标签（JSON格式存储）
     */
    @TableField("tags")
    private String tags;
    
    /**
     * 文件状态：0-上传中，1-正常，2-处理中，3-已损坏，4-已删除
     */
    @TableField("status")
    private Integer status;
    
    /**
     * 是否公开访问
     */
    @TableField("is_public")
    private Boolean isPublic;
    
    /**
     * 访问权限配置（JSON格式）
     */
    @TableField("access_permissions")
    private String accessPermissions;
    
    /**
     * 上传者ID
     */
    @TableField("uploader_id")
    private String uploaderId;
    
    /**
     * 上传者名称
     */
    @TableField("uploader_name")
    private String uploaderName;
    
    /**
     * 上传IP地址
     */
    @TableField("upload_ip")
    private String uploadIp;
    
    /**
     * 上传时间
     */
    @TableField("upload_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime uploadTime;
    
    /**
     * 最后访问时间
     */
    @TableField("last_access_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime lastAccessTime;
    
    /**
     * 访问次数
     */
    @TableField("access_count")
    private Long accessCount;
    
    /**
     * 下载次数
     */
    @TableField("download_count")
    private Long downloadCount;
    
    /**
     * 过期时间（可选）
     */
    @TableField("expire_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime expireTime;
    
    /**
     * 文件描述
     */
    @TableField("description")
    private String description;
    
    /**
     * 扩展属性（JSON格式存储）
     */
    @TableField("extra_attributes")
    private String extraAttributes;
    
    // ==================== 便捷方法 ====================
    
    /**
     * 判断文件是否有效（状态正常且未过期）
     */
    public boolean isValid() {
        if (status == null || status != 1) {
            return false;
        }
        if (expireTime != null && LocalDateTime.now().isAfter(expireTime)) {
            return false;
        }
        return true;
    }
    
    /**
     * 判断是否为图片文件
     */
    public boolean isImage() {
        return mimeType != null && mimeType.startsWith("image/");
    }
    
    /**
     * 判断是否为视频文件
     */
    public boolean isVideo() {
        return mimeType != null && mimeType.startsWith("video/");
    }
    
    /**
     * 判断是否为音频文件
     */
    public boolean isAudio() {
        return mimeType != null && mimeType.startsWith("audio/");
    }
    
    /**
     * 判断是否为文档文件
     */
    public boolean isDocument() {
        if (mimeType == null) return false;
        return mimeType.startsWith("application/pdf") ||
               mimeType.startsWith("application/msword") ||
               mimeType.startsWith("application/vnd.openxmlformats-officedocument") ||
               mimeType.startsWith("text/");
    }
    
    /**
     * 判断是否已过期
     */
    public boolean isExpired() {
        return expireTime != null && LocalDateTime.now().isAfter(expireTime);
    }
    
    /**
     * 获取文件大小的人类可读格式
     */
    public String getHumanReadableSize() {
        if (fileSize == null || fileSize <= 0) {
            return "0 B";
        }
        
        String[] units = {"B", "KB", "MB", "GB", "TB"};
        int unitIndex = 0;
        double size = fileSize.doubleValue();
        
        while (size >= 1024 && unitIndex < units.length - 1) {
            size /= 1024;
            unitIndex++;
        }
        
        return String.format("%.1f %s", size, units[unitIndex]);
    }
    
    // ==================== Getter/Setter ====================
    
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public String getStorageObjectId() {
        return storageObjectId;
    }
    
    public void setStorageObjectId(String storageObjectId) {
        this.storageObjectId = storageObjectId;
    }
    
    public String getOriginalName() {
        return originalName;
    }
    
    public void setOriginalName(String originalName) {
        this.originalName = originalName;
    }
    
    public String getDisplayName() {
        return displayName;
    }
    
    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }
    
    public String getFileExtension() {
        return fileExtension;
    }
    
    public void setFileExtension(String fileExtension) {
        this.fileExtension = fileExtension;
    }
    
    public String getMimeType() {
        return mimeType;
    }
    
    public void setMimeType(String mimeType) {
        this.mimeType = mimeType;
    }
    
    public Long getFileSize() {
        return fileSize;
    }
    
    public void setFileSize(Long fileSize) {
        this.fileSize = fileSize;
    }
    
    public String getContentMd5() {
        return contentMd5;
    }
    
    public void setContentMd5(String contentMd5) {
        this.contentMd5 = contentMd5;
    }
    
    public String getContentSha256() {
        return contentSha256;
    }
    
    public void setContentSha256(String contentSha256) {
        this.contentSha256 = contentSha256;
    }
    
    public String getBusinessKey() {
        return businessKey;
    }
    
    public void setBusinessKey(String businessKey) {
        this.businessKey = businessKey;
    }
    
    public String getBusinessType() {
        return businessType;
    }
    
    public void setBusinessType(String businessType) {
        this.businessType = businessType;
    }
    
    public String getTags() {
        return tags;
    }
    
    public void setTags(String tags) {
        this.tags = tags;
    }
    
    public Integer getStatus() {
        return status;
    }
    
    public void setStatus(Integer status) {
        this.status = status;
    }
    
    public Boolean getIsPublic() {
        return isPublic;
    }
    
    public void setIsPublic(Boolean isPublic) {
        this.isPublic = isPublic;
    }
    
    public String getAccessPermissions() {
        return accessPermissions;
    }
    
    public void setAccessPermissions(String accessPermissions) {
        this.accessPermissions = accessPermissions;
    }
    
    public String getUploaderId() {
        return uploaderId;
    }
    
    public void setUploaderId(String uploaderId) {
        this.uploaderId = uploaderId;
    }
    
    public String getUploaderName() {
        return uploaderName;
    }
    
    public void setUploaderName(String uploaderName) {
        this.uploaderName = uploaderName;
    }
    
    public String getUploadIp() {
        return uploadIp;
    }
    
    public void setUploadIp(String uploadIp) {
        this.uploadIp = uploadIp;
    }
    
    public LocalDateTime getUploadTime() {
        return uploadTime;
    }
    
    public void setUploadTime(LocalDateTime uploadTime) {
        this.uploadTime = uploadTime;
    }
    
    public LocalDateTime getLastAccessTime() {
        return lastAccessTime;
    }
    
    public void setLastAccessTime(LocalDateTime lastAccessTime) {
        this.lastAccessTime = lastAccessTime;
    }
    
    public Long getAccessCount() {
        return accessCount;
    }
    
    public void setAccessCount(Long accessCount) {
        this.accessCount = accessCount;
    }
    
    public Long getDownloadCount() {
        return downloadCount;
    }
    
    public void setDownloadCount(Long downloadCount) {
        this.downloadCount = downloadCount;
    }
    
    public LocalDateTime getExpireTime() {
        return expireTime;
    }
    
    public void setExpireTime(LocalDateTime expireTime) {
        this.expireTime = expireTime;
    }
    
    public String getDescription() {
        return description;
    }
    
    public void setDescription(String description) {
        this.description = description;
    }
    
    public String getExtraAttributes() {
        return extraAttributes;
    }
    
    public void setExtraAttributes(String extraAttributes) {
        this.extraAttributes = extraAttributes;
    }
    
    @Override
    public String toString() {
        return "FileInfo{" +
                "id='" + id + '\'' +
                ", storageObjectId='" + storageObjectId + '\'' +
                ", originalName='" + originalName + '\'' +
                ", displayName='" + displayName + '\'' +
                ", fileExtension='" + fileExtension + '\'' +
                ", mimeType='" + mimeType + '\'' +
                ", fileSize=" + fileSize +
                ", contentMd5='" + contentMd5 + '\'' +
                ", contentSha256='" + contentSha256 + '\'' +
                ", businessKey='" + businessKey + '\'' +
                ", businessType='" + businessType + '\'' +
                ", status=" + status +
                ", isPublic=" + isPublic +
                ", uploaderId='" + uploaderId + '\'' +
                ", uploaderName='" + uploaderName + '\'' +
                ", uploadTime=" + uploadTime +
                ", accessCount=" + accessCount +
                ", downloadCount=" + downloadCount +
                ", expireTime=" + expireTime +
                '}';
    }
}
